package com.stox.client.ui.javafx.chartingy.model.node;

import javafx.scene.layout.Region;
import javafx.scene.paint.Color;

import com.stox.client.ui.javafx.chartingy.model.axis.DateAxis;
import com.stox.client.ui.javafx.chartingy.model.axis.ValueAxis;
import com.stox.client.ui.javafx.chartingy.model.plot.Data;
import com.stox.client.ui.javafx.chartingy.model.plot.Plot;
import com.stox.client.ui.javafx.core.util.CSS;
import com.stox.client.ui.javafx.core.util.UI;
import com.stox.shared.model.Bar;
import com.stox.shared.model.Scrip;
import com.stox.shared.util.MathUtil;

public class VolumeDataNode extends AbstractPriceNode {
	private static final double LOW_OPACITY = 0.3;

	private final Region region = new Region();

	public VolumeDataNode(final Data<Scrip, Bar> data) {
		super(data);
		UI.style(this, CSS.barNode, CSS.volumeNode);
		getChildren().add(region);
		updateColor();
	}

	@Override
	public void updateColor() {
		final DataNode<Scrip, Bar> primaryDataNode = getData().primaryPlot().getData().get(getData().getIndex()).getDataNode();
		final Color color = primaryDataNode == null ? getData().primaryPlot().getColor() : primaryDataNode.getColor();
		setStyle("-fx-bar-color:" + UI.web(color) + ";");

		if (getData().getPlot().isPrimary()) {
			setOpacity(1);
		} else {
			setOpacity(LOW_OPACITY);
		}
	}

	@Override
	public void layoutChartChildren() {
		final Data<Scrip, Bar> data = getData();
		final DataNode<Scrip, Bar> primaryDataNode = data.primaryPlot().getData().get(data.getIndex()).getDataNode();

		double x = 0;
		double width = 0;
		if (null == primaryDataNode) {
			final DateAxis dateAxis = data.primaryChart().getDateAxis();
			x = dateAxis.getDisplayPosition(data.getIndex());
			width = dateAxis.getUnitWidth();
		} else {
			x = primaryDataNode.getRectangle().getX();
			width = primaryDataNode.getRectangle().getWidth();
		}

		final ValueAxis valueAxis = data.chart().getValueAxis();
		if (getData().getPlot().isPrimary()) {
			setOpacity(1);
		} else {
			setOpacity(LOW_OPACITY);
		}
		final double y = getDisplayPosition(data.getValue());
		region.resizeRelocate(x, y, width, valueAxis.getHeight() - y);
	}

	@Override
	protected double getDisplayPosition(final double value) {
		final Plot<?, ?> plot = getData().getPlot();
		/**
		 * Volume plot does not care about maintain ratio
		 */
		if (plot.isPrimary()/* || plot.getChart().isMaintainRatio() */) {
			return plot.getChart().getValueAxis().getDisplayPosition(value);
		} else {
			double min = getData().getPlot().getMin();
			double max = getData().getPlot().getMax();
			final ValueAxis axis = plot.getChart().getValueAxis();
			if (plot.getChart().getValueAxis().isZoomable()) {
				min = plot.getBackingDataMin();
				max = plot.getBackingDataMax();
				final double priceEquivalent = MathUtil.praportion(min, value, max, plot.primaryPlot().getBackingDataMin(), plot.primaryPlot().getBackingDataMax());
				return axis.getDisplayPosition(priceEquivalent);
			} else {
				final double height = axis.getHeight();
				return height - MathUtil.praportion(min, value, max, 0, height);
			}
		}
	}

}
